package datos;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;


public class Muestra {
	private List<Atributo<?>> atributos;
    private List<Dato> datos;

    public static class Builder implements IBuilder<Dato, Muestra> {
        private List<Atributo<?>> atributos;
        private ArrayList<Dato> datos;

        public Builder(List<Atributo<?>> atributos) {
            this.atributos = atributos;
            this.reset();
        }

        @Override
        public void add(Dato d) {
            this.datos.add(d);
        }

        @Override
        public void reset() {
            this.datos = new ArrayList<Dato>();
        }

        @Override
        public Muestra finish() {
            Muestra muestra = new Muestra(atributos, datos);
            this.reset();
            return muestra;
        }
    }

    public Muestra(Muestra m)
    {
        this.atributos = m.atributos;
        this.datos     = m.datos;
    }
    public Muestra(List<Atributo<?>> atributos)
    {
    	this.atributos = atributos;
    }
    public Muestra(List<Atributo<?>> atributos, List<Dato> datos)
    {
        this(atributos);
        this.datos = datos;
    }
    
    public List<Atributo<?>> getAtributos()
    {
    	return atributos;
    }
    
    public List<Dato> getDatos()
    {
    	return datos;
    }    

    public int size()
    { 
        return this.datos.size();
    }
    
    public class Rango
    {
        private int comienzo;
        private int fin;
        
        public Rango(int comienzo, int fin)
        {
        	this.comienzo = comienzo;
        	this.fin = fin;
        }

        public Muestra getInside()
        {
            List<Dato> inside = datos.subList(comienzo, fin);

            return new Muestra(atributos, inside);
        }

        public Muestra getOutside()
        {
            List<Dato> outside = new ArrayList<Dato>(datos.size()-(fin-comienzo));

            outside.addAll(datos.subList(0,comienzo));
            outside.addAll(datos.subList(fin,datos.size()));

            return new Muestra(atributos, outside);
        }
        
        public Muestra getMuestra()
        {
        	return Muestra.this;
        }
    }

    public boolean fitsDefinition(Dato d) {
        Set<Atributo<?>> atributos = d.getAtributos();

        return atributos.containsAll(this.getAtributos())
            && this.getAtributos().containsAll(atributos); 
    }
}
